//-----------------------------------------------------------------------
// <copyright file="DataProvider.cs" company="Simnova LLC">
//     Copyright (c) Simnova LLC. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Simnova.Collaborate.ServiceImplementation
{
    using System;
    using System.Collections.Generic;
    using Simnova.Collaborate.ServiceContract.DataClasses;

    /// <summary>
    /// The DataProvider class abstracts all data access using the provider model.
    /// </summary>
    public abstract class DataProvider
    {
        #region Shared/Static Methods

        // singleton reference to the instantiated object 
        private static DataProvider provider;

        /// <summary>
        /// Static Constructor for the DataProvider class.
        /// </summary>
        static DataProvider()
        {
            CreateProvider();
        }

        // return the provider
        public static DataProvider Instance()
        {
            if (provider == null)
            {
                CreateProvider();
            }

            return provider;
        }

        #endregion

        #region Feedback

        public abstract IList<Product> GetProductsByCompany(int companyId);
        public abstract Product GetProduct(int productId);
        public abstract Feedback GetFeedback(int feedbackId);
        public abstract FeedbackComment GetFeedbackCommentByFeedback(int userId, int feedbackId);
        public abstract FeedbackRating GetFeedbackRatingByFeedback(int userId, int feedbackId);
        public abstract FeedbackWatchList GetFeedbackWatchListByFeedback(int userId, int feedbackId);
        public abstract FeedbackWorkaround GetFeedbackWorkaroundByFeedback(int userId, int feedbackId);
        public abstract IList<Feedback> GetProductFeedback(int productId);
        public abstract IList<Feedback> GetTopRatedProductFeedback(int productId, int quantity);
        public abstract IList<Feedback> GetWatchListProductFeedback(int productId, int userId, int quantity);
        public abstract IList<Feedback> GetNewestProductFeedback(int productId, int quantity);
        public abstract IList<Feedback> GetProductFeedbackByUser(int productId, int userId);
        public abstract IList<FeedbackWatchList> GetFeedbackWatchListByUser(int productId, int userId);
        public abstract IList<FeedbackComment> GetFeedbackComments(int feedbackId);
        public abstract IList<FeedbackRating> GetFeedbackRatings(int feedbackId);
        public abstract IList<FeedbackWorkaround> GetFeedbackWorkarounds(int feedbackId);
        public abstract void SaveProduct(Product product);
        public abstract void SaveFeedback(Feedback feedback);
        public abstract void SaveFeedbackComment(FeedbackComment feedbackComment);
        public abstract void SaveFeedbackRating(FeedbackRating feedbackRating);
        public abstract void SaveFeedbackWatchList(FeedbackWatchList feedbackWatchList);
        public abstract void DeleteFeedbackWatchList(FeedbackWatchList feedbackWatchList);
        public abstract void SaveFeedbackWorkaround(FeedbackWorkaround feedbackWorkaround);

        #endregion

        #region Company
        public abstract Company GetCompany(int companyId);
        public abstract void SaveCompany(Company company, int userId);
        public abstract IList<Company> GetCompanies();
        #endregion

        #region Project
        public abstract Project GetProject(int projectId);
        public abstract void SaveProject(Project project);
        public abstract IList<Project> GetProjectsByCompany(int companyId);
        #endregion

        #region Task
        public abstract Task GetTask(int taskId);
        public abstract void SaveTask(Task task);
        public abstract void AssignTask(int taskId, int userId);
        public abstract IList<Task> GetTasksByProject(int projectId);
        public abstract IList<Task> GetTasksByUser(int userId);
        public abstract IList<User> GetUsersByTask(int taskId);
        #endregion

        #region User
        public abstract User GetUserById(int userId);
        public abstract User GetUserByEmailAddress(string emailAddress);
        public abstract User GetUser(string emailAddress, string password);
        public abstract void SaveUser(User user);
        public abstract IList<CompanyUser> GetCompanyUsersByCompany(int companyId);
        public abstract IList<User> GetUsers();

        public abstract IList<Company> GetCompaniesByAdministrator(int userId);
        public abstract IList<Company> GetCompaniesByUser(int userId);

        public abstract void SaveUserRole(UserRole userRole);
        public abstract void SaveActivityType(ActivityType activityType);
        public abstract IList<ActivityType> GetActivityTypesByRole(int roleId);
        public abstract IList<Role> GetRolesByCompany(int companyId);
        public abstract IList<Role> GetRolesByUserCompany(int userId, int companyId);
        public abstract void SaveRole(Role role);

        #endregion

        #region TimeLog
        public abstract IList<TimeLog> GetTimeLogByUser(int userId);
        public abstract TimeLog GetCurrentTimeLog(int userId);
        public abstract void SaveTimeLog(TimeLog timeLog);
        public abstract void DeleteTimeLog(TimeLog timeLog);
        #endregion

        // dynamically create provider
        private static void CreateProvider()
        {
            string assemblyPath = System.IO.Path.GetDirectoryName((new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase)).LocalPath) + System.IO.Path.DirectorySeparatorChar + System.Configuration.ConfigurationManager.AppSettings.Get("DataAccessAssemblyName");
            System.Reflection.Assembly assemb = System.Reflection.Assembly.LoadFrom(assemblyPath);
            provider = (DataProvider)assemb.CreateInstance(System.Configuration.ConfigurationManager.AppSettings.Get("DataAccessClass"));
        }
    }
}
